#!/usr/bin/perl

# ---------- Init variables -------
#my $version = "0.0001";
# ---------- external readable parameters -------
## Functions
##-------------------------------------------------------
#
# stict syntax checking.
require Exporter;
use strict;
use SNMP_util;
use SIM_settings;
use SIM_cgiSettings;
use SIM_base;
use SIM_cgi;
use SIM_nodeInfo;
use SIM_report;
use CGI qw(param);

#my $httpUser = $ENV{'REMOTE_USER'} || die "Oops no env found for SREMOTE_USER.";
my $tool = $ARGV[0];
my $action = $ARGV[1];
my $devType = $ARGV[2];
my $option1 = $ARGV[3];
my $option2 = $ARGV[4];
my $option3 = $ARGV[5];
my $option4 = $ARGV[6];

my $baseUrl = "$httpScriptName?$tool";
my $devBaseDir = $SIMparam{'SIMdeviceDir'};
$SNMP_Session::suppress_warnings = 1000;



sub printHead {
  my $dispHead = "@_[0]";
  print("<FONT COLOR=#666666>");
  if ( -d $devBaseDir ) {
    chdir $devBaseDir;
    my @dirEntries = ();
    my $first = "yes";
    my $groupName = catFileLine("$SIMparam{'SIMpasswdUserDir'}/$remoteUser/group");
    my $devicesVisible = catFileLine("$SIMparam{'SIMpasswdGroupDir'}/$groupName/devicesVisible");
    if ( $devicesVisible eq "all" ) {
      @dirEntries = <*>;
    } else {
      # if only certain device types will be visible, test if they exist.
      my @testList = split(' ', $devicesVisible);
      foreach my $entry (@testList) {
        if ( -d "$devBaseDir/$entry" ) {
          push(@dirEntries, $entry);
        }
      }
    }
    foreach my $entry (@dirEntries) {
      if ( "$first" eq "no" ) {
        print(" | ");
      } else {
        $first = "no";
      }
      my $fontColor;
      if ( "$devType" eq "$entry" ) {
        $fontColor = "red";
      } else {
        $fontColor = "#444444";
      }
      print(" <A HREF=$baseUrl+none+$entry+$option1><FONT COLOR=$fontColor>$entry</FONT></A> ");
    }
#   print(" / ");
#   printMenu("dev","line", $tool, $action);
    print("
        </FONT>
        </TD></TR>");
    if ((( "$action" eq "none" ) or ( "$action" eq "cleanList" ) or ( "$action" eq "ipList")) and ( "$devType" ne "none" )) {
      my $fontColor = "#444444";
      print("<TR BGCOLOR=#EEEEEE><TD COLSPAN=9><CENTER>Actions: ");
      printEntry("quickLinks", "The quicklink table.", "dev", "none", "2", "$tool", "$action", "$devType+$option1+$option2", "line" , "", $fontColor);
      printEntry("ipList", "Display the node list.", "dev", "ipList", "2", "$tool", "$action", "$devType", "line" , "/", $fontColor);
      printEntry("cleanDevices", "clean the device list.", "dev", "cleanList", "2", "$tool", "$action", "$devType", "line" , "/", $fontColor);


      print("</TD></TR>");
    }
    print("</TABLE>");
  } else {
    print ("Oops, no dir $devBaseDir found.");
    exit;
  }
}

sub cleanList {
  my $devType = "@_[0]";
  my $option = "@_[1]";
  if ( "$devType" eq "" ) {
    print("<CENTER><H2>Select the device type above</H2>");
  } elsif ( ! -d "$devBaseDir/$devType" ) {
    print("<CENTER><H2>Oops, no info found for type $devType</H2>");
  } elsif ( ! -w "$devBaseDir/$devType" ) {
    print("<CENTER><H2>Oops, data for $devType not writeable.</H2>");
  } else {
    chdir "$devBaseDir/$devType";
    print("Listing: $devBaseDir/$devType ");
    my @dirEntries = <*>;
    print("<CENTER>");
    foreach my $entry (@dirEntries) {
      print("Testing $entry. ");
      if ( -f $entry ) {
        print("Removing file $entry.");
        system(" rm -fR $devBaseDir/$devType/$entry ");    
      } elsif ( ! -f "$devBaseDir/$devType/$entry/ipaddr" ) {
        print("no ip address found for the node, removing the stuff. ");
        system(" rm -fR $devBaseDir/$devType/$entry ");
      } else {
        my $ipAddr = catFileLine("$devBaseDir/$devType/$entry/ipaddr");
        my $ipDir = getIpDir( $ipAddr );
        my $devHostName = catFileLine("$devBaseDir/$devType/$entry/hostname");
        my $ipHostName = catFileLine("$ipDir/hostname.txt");
        if ( "$devHostName" ne "$ipHostName" ) {
          print("Device hostname $devHostName differs from $ipHostName, removing. ");
	  removeNode($devType, $entry, $option);
	} else {
          my $vendor = catFileLine("$ipDir/vendor");
          if ( $devType ne $vendor ) {
            print("Device hostname $devHostName has vendor $vendor, removing. ");
	    removeNode($devType, $entry, $option);
          }
        }
      }
      print("<BR>");
    }
    if ( "$option" ne "confirm" ) {
      print("<A HREF=$baseUrl+cleanList+$devType+confirm><FONT SIZE=+1>Remove the above nodes</A>");
    }
  }
}

sub ipList {
  my $devType = "@_[0]";
  if ( "$devType" eq "" ) {
    print("<CENTER><H2>Select the device type above</H2>");
  } elsif ( -d "$devBaseDir/$devType" ) {
    print("<CENTER>");
    chdir "$devBaseDir/$devType";
    my @dirEntries = <*>;
#   print("<TABLE>");
    my $cacheFile = "$devType-$$";
    open( OUT, ">$SIMparam{'SIMtmpDir'}/$cacheFile" ) || die "Problems creating cachfile $cacheFile.";
    foreach my $entry (@dirEntries) {
      if ( -f "$devBaseDir/$devType/$entry/ipaddr" ) {
        my $ipAddr = catFileLine("$devBaseDir/$devType/$entry/ipaddr");
        print OUT "$ipAddr\n";
      }
    }
    close OUT;
    searchIndex( "mon", "listCache", $cacheFile );
#   print("</TABLE>");
  }
}

sub listNodes {
  my $devType = "@_[0]";
  if ( "$devType" eq "" ) {
    print("<CENTER><H2>Select the device type above</H2>");
  } elsif ( $devType eq "none" ) {
    print("<CENTER><H2>Please select one of the device types above.</H2>");
  } elsif ( ! -w "$devBaseDir/$devType" ) {
    print("<CENTER><H2>Oops, devicelist for $devType not readable.</H2>");
  } elsif ( -d "$devBaseDir/$devType" ) {
    print("<CENTER>");
    chdir "$devBaseDir/$devType";
    my @dirEntries = <*>;
    if ( $#dirEntries eq -1 ) {
      print("<H2>No devices found for $devType, removing it.</H2>");
      # jump to the parent directory and remove the empty directory.
      system(" cd ..; rmdir $devBaseDir/$devType ");
    } else {
      print("<TABLE>
              <TR BGCOLOR=#FFFF88><TD></TD><TD>Device name</TD><TD COLSPAN=99>Properties (quick links)</TD></TR>");
      my $entryNum = 0;
      foreach my $entry (@dirEntries) {
        my $ipAddr = catFileLine("$devBaseDir/$devType/$entry/ipaddr");
        my $ipDir = getIpDir( $ipAddr );
        my $devHostName = catFileLine("$devBaseDir/$devType/$entry/hostname");
        my $ipHostName = catFileLine("$ipDir/hostname.txt");
        my ( $statusColor, $altName );
        if ( "$devHostName" ne "$ipHostName" ) {
          $statusColor = "#00CCCC";
	  $altName = "($ipHostName)";
        } else {
          $statusColor = testNodeStatus( $ipAddr );
        }
        $entryNum++;
        print("<TR BGCOLOR=#FFFFDD><TD ALIGN=right>$entryNum</TD>
                   <TD BGCOLOR=$statusColor><A HREF=$baseUrl+dispNode+$devType+$entry><FONT COLOR=#444444>$entry</FONT></A> $altName</TD>
	  	   ");
        dispInfo( $devType, $entry, "table" );
        print("</TR>");
      }
      print("</TABLE>");
    }
  } else {
    print ("<CENTER><H3>Please select a device type above.</H3>");
  }
}

sub dispInfo {
  my $devType = "@_[0]";
  my $nodeName = "@_[1]";
  my $displayType = "@_[2]";
  my ( $dispStart, $dispEnd );
  if ( $displayType eq "table") {
    $dispStart = "<TD>";
    $dispEnd = "</TD>";
  } else {
    $dispStart = "-";
  }
  my $ipAddr = catFileLine("$SIMparam{'SIMdeviceDir'}/$devType/$nodeName/ipaddr");
  my $ipDir = getIpDir( $ipAddr );
  if ( -d "$ipDir" ) { print("$dispStart <A HREF=$httpScriptName?mon+nodestatus+$ipAddr>nodeStatus</A> $dispEnd
       $dispStart <A HREF=telnet://$ipAddr>telnet</A> $dispEnd
       $dispStart <A HREF=ssh://$ipAddr>ssh</A> $dispEnd"); 
  } else {
    print("<TD></TD><TD></TD><TD></TD>");
  }
  if ( -f "$SIMparam{'SIMswitchDevices'}/$nodeName/dot1x" ) { 
    print("$dispStart <A HREF=$httpScriptName?switch2+displaySwitch+$nodeName>isDot1x</A> $dispEnd"); 
  } elsif ( -d "$SIMparam{'SIMswitchDevices'}/$nodeName" ) { 
    print("$dispStart <A HREF=$httpScriptName?switch2+displaySwitch+$nodeName>isSwitch</A> $dispEnd"); 
  } else {
    print("<TD></TD>");
  }
  if ( -f "$SIMparam{'SIMgraphConfDir'}/$devType/$nodeName/graphinfo.conf" ) { 
     print("$dispStart <A HREF=$httpScriptName?graph+main+$devType+$nodeName>hasGraph</A> $dispEnd"); 
  } else {
    print("<TD></TD>");
  }
  if ( -d "$SIMparam{'SIMdevConfigHistory'}/$nodeName" ) { 
    print("$dispStart <A HREF=$httpScriptName?file2+listDevConfigsHistory+name+$nodeName>hasConfig</A> $dispEnd"); 
  } else {
    print("<TD></TD>");
  }
}

sub dispNode {
  my $devType = "@_[0]";
  my $nodeName = "@_[1]";
  my %l2Param = ();
  open ( PARAM, $SIMparam{'SIMInterfaceParams'} );
  my @info = <PARAM>;
  close PARAM;
# printDebug( 0, "Interface parameters.");
  foreach my $entry (@info) {
    chomp $entry;
    my ( $test, $type, $rest ) = split(' ', $entry);
    if ( $test eq "int" ) {
      $l2Param{$type} = "non";
      my @parts = split(';', $rest);
      foreach my $param (@parts) {
        if ( "$param" eq "l2mon" ) {
          $l2Param{$type} = "l2";
        }
      }
#     print("\n$type: l2Param=$l2Param{$type}.");
    }
  }
  print("<CENTER><H3>Info for $nodeName ($devType)</H3>QuickLinks: ");
  dispInfo( $devType, $nodeName );
  printEntry2("Remove","Remove the node", "dev+removeNode", "dev+removeNode+$devType+$nodeName", "", "line", "Actions:", "");
  print("  
	  <HR><B>Under devellopment<P>
	    Furter information will follow in the next release of this tool</B>
        ");
  my $ipAddr = catFileLine("$devBaseDir/$devType/$nodeName/ipaddr");
  my $ipDir = getIpDir( $ipAddr );
  my $macAddr = catFileLine("$ipDir/firstmac.txt");
# print(" ipAddr=$ipAddr, ipDir=$ipDir, macAddr=$macAddr<BR>$SIMparam{'SIMmacDatab'}/$macAddr<BR>");
  if (( "$macAddr" ne "" ) and ( -d "$SIMparam{'SIMmacDatab'}/$macAddr" )) {
    chdir("$SIMparam{'SIMmacDatab'}/$macAddr");
    my @intList = <l2Int-*>;
    my @intNums;
    foreach my $entry (@intList) {
      my $intNum = substr($entry, 6);
#     print("$intNum ");
      push(@intNums,$intNum);
    }
    my @sortNums = sort {$a <=> $b} (@intNums);
    my $community = catFileLine("$ipDir/snmpcomm.txt");
    my $SNMPSTR = $community . "@" . $ipAddr . ":::::" . "1";
    my $testStatus = snmpget("$SNMPSTR", "1.3.6.1.2.1.2.2.1.8.$sortNums[0]");
    print("<TABLE><TR BGCOLOR=#CCCCCC><TD>intNo</TD><TD>intName</TD><TD>intSpeed</TD><TD COLSPAN=2>intType</TD><TD>intDescription</TD></TR>");
    foreach my $entry (@sortNums) {
      my ($intStatus, $intAdmin);
      my $intColor = "#CCCCCC";
      if ( "$testStatus" ne "" ) {
        $intStatus = snmpget("$SNMPSTR", "1.3.6.1.2.1.2.2.1.8.$entry");
	if ( "$intStatus" ne "1" ) {
          $intAdmin = snmpget("$SNMPSTR", "1.3.6.1.2.1.2.2.1.7.$entry");
          if ( "$intAdmin" ne "1" ) {
	    $intColor = $ipColor{ 'Unmanaged' };
	  } else {
	    $intColor = $ipColor{ 'Down' };
	  }
	} else {
	  $intColor = $ipColor{ 'Up' };
	}
      }
      my $workDir = "$SIMparam{'SIMmacDatab'}/$macAddr/l2Int-$entry";
      my $intName = catFileLine("$workDir/intName");
      my $intDescription = catFileLine("$workDir/intDescription");
      my $intType  = catFileLine("$workDir/intType");
      my $dIntSpeed = catFileLine("$workDir/dIntSpeed");
#     print("<TR><TD BGCOLOR=$intColor>$entry, $intStatus, $intAdmin</TD>
      print("<TR><TD BGCOLOR=$intColor ALIGN=center>$entry</TD>
                 <TD>$intName</TD>
                 <TD ALIGN=right>$dIntSpeed</TD>
		 <TD>$intType</TD>
		 <TD>$l2Param{$intType}</TD>
		 <TD>$intDescription</TD>
	     </TR>");
    }
    print("<TABLE>");
  }

}

sub removeNode {
  my $devType = "@_[0]";
  my $nodeName = "@_[1]";
  my $confirm = "@_[2]";
  print("<CENTER>");
  if ( "$confirm" ne "remove" ) {
    print("<B>Information to remove for $nodeName ($devType)</B><HR>");
  } else {
    print("<B>Removing information for $nodeName ($devType)</B><HR>");
  }
  print("<TABLE>");
  my $devHostName = catFileLine("$devBaseDir/$devType/$nodeName/hostname");
  my %dirEntry = ();
  $dirEntry{'SIMswitchDevices'} = "$SIMparam{'SIMswitchDevices'}/$nodeName";
  $dirEntry{'SIMgrahdirhConfDir'} = "$SIMparam{'SIMgraphConfDir'}/$devType/$nodeName";
  $dirEntry{'SIMgraphDataDir'} = "$SIMparam{'SIMgraphDataDir'}/$devType/$nodeName";
# $dirEntry{'SIMdevConfigHistory'} = "$SIMparam{'SIMdevConfigHistory'}/$nodeName";
  $dirEntry{'SIMdevConfigCurrent'} = "$SIMparam{'SIMdevConfigCurrent'}/$nodeName";
  $dirEntry{'SIMdeviceDir'} = "$SIMparam{'SIMdeviceDir'}/$devType/$nodeName";
  my $ipAddr = catFileLine("$SIMparam{'SIMdeviceDir'}/$devType/$nodeName/ipaddr");
  my $ipDir = getIpDir( $ipAddr );
  my $macAddr = catFileLine("$ipDir/firstmac.txt");
  if ( "$macAddr" ne "" ) {
    my @intList = <$SIMparam{'SIMmacDatab'}/$macAddr/ipint-*>;
    foreach my $ipInt (@intList) {
      my $intInfo = catFileLine("$ipInt");
      my ( $intIpAddr, $rest ) = split(' ', $intInfo);
      my $ipDir = getIpDir( $intIpAddr );
      my $ipHostName = catFileLine("$ipDir/hostname.txt");
      if ( "$ipHostName" eq "$devHostName" ) {
        $dirEntry{$intIpAddr} = $ipDir;
      } else {
        $dirEntry{$intIpAddr} = "Skip";
      }
    }
  }
  while ( my ($key, $value) = each(%dirEntry) ) {
    my $bgColor;
    if ( "$value" eq "Skip" ) {
      $bgColor = "white";
    } elsif ( -f $value ) {
      $bgColor = "#00CC00";
    } elsif ( -d $value ) {
      $bgColor = "#00CCCC";
    } else {
      $bgColor = "white";
    }
    my $status;
    if (( "$bgColor" ne "white" ) and ( "$confirm" ne "" )) {
      system(" rm -fR $value ");
      if (( ! -f $value ) and ( ! -d $value )) {
        $status = "REMOVED";
      } else {
        $status = "FAILED";
      }
    }
    print "<TR><TD BGCOLOR=$bgColor>$key</TD><TD>=> $value</TD><TD>$status</TD></TR>";
  }

  print("</TABLE><HR>
           <A HREF=$baseUrl+removeNode+$devType+$nodeName+remove><B>Confirm remove</B></A>
        ");
}




#--------------------------- Main ---------------------------
printHead;

if ( "$action" eq "dispNode" ) {
  dispNode($devType, $option1);
} elsif ( "$action" eq "ipList" ) {
  ipList($devType, $option1);
} elsif ( "$action" eq "removeNode" ) {
  removeNode($devType, $option1, $option2 );
} elsif ( "$action" eq "cleanList" ) {
  cleanList($devType, $option1);
} else {
  listNodes($devType);
}
